package rtda

import (
	"hi-jvm/rtda/heap"
	"math"
)

// 局部变量表
// 局部变量表是按索引访问的
type LocalVars []Slot


func newLocalVars(maxLocals uint) LocalVars {
	if maxLocals > 0 {
		return make([]Slot, maxLocals)
	}
	return nil
}

func (self LocalVars)SetInt(index uint, val int32) {
	self.checkLen(index)
	self[index].Num = val
}

func (self LocalVars)GetInt(index uint) int32 {
	self.checkLen(index)
	return self[index].Num
}

func (self LocalVars)SetFloat(index uint, val float32) {
	self.checkLen(index)
	bits := math.Float32bits(val)
	self[index].Num = int32(bits)
}

func (self LocalVars)GetFloat(index uint) float32 {
	self.checkLen(index)
	bits := uint32(self[index].Num)
	return math.Float32frombits(bits)
}

// Long需要拆成两个int变量
func (self LocalVars)SetLong(index uint, val int64) {
	self.checkLen(index + 1)
	self[index].Num = int32(val)
	self[index + 1].Num = int32(val >> 32)
}

// Long需要拆成两个int变量
func (self LocalVars)GetLong(index uint) int64 {
	self.checkLen(index + 1)
	low := uint32(self[index].Num)
	high := uint32(self[index + 1].Num)
	return int64(high) << 32 | int64(low)
}

// double变量可以先转换成long类型，然后按照long变量处理
func (self LocalVars)SetDouble(index uint, val float64) {
	self.checkLen(index)
	bits := math.Float64bits(val)
	self.SetLong(index, int64(bits))
}

// double变量可以先转换成long类型，然后按照long变量处理
func (self LocalVars)GetDouble(index uint) float64 {
	self.checkLen(index)
	bits := uint64(self.GetLong(index))
	return math.Float64frombits(bits)
}

func (self LocalVars)SetRef(index uint, ref *heap.Object) {
	self.checkLen(index)
	self[index].Ref = ref
}

func (self LocalVars)GetRef(index uint) *heap.Object {
	self.checkLen(index)
	return self[index].Ref
}

func (self LocalVars)checkLen(index uint) {
	if len(self) < int(index) {
		panic("java.lang localvars length of stack is less ")
	}
}

func (self LocalVars) SetSlot(index uint, slot Slot) {
	self[index] = slot
}


